|
ARD2
RC2
Airbag Reference Demonstrator using MPC5604P
|
00001 /****************************************************************************** 00002 * 00003 * Freescale Semiconductor Inc. 00004 * (c) Copyright 2004-2010 Freescale Semiconductor 00005 * ALL RIGHTS RESERVED. 00006 * 00007 ****************************************************************************/ 00019 #include "freemaster.h" 00020 #include "freemaster_private.h" 00021 #include "freemaster_protocol.h" 00022 00023 #if FMSTR_USE_CAN 00024 00025 /*********************************** 00026 * CAN low-level access macros 00027 ***********************************/ 00028 00029 #if FMSTR_USE_MSCAN 00030 00031 #define FMSTR_CAN_ETXI() FMSTR_MSCAN_ETXI() 00032 #define FMSTR_CAN_DTXI() FMSTR_MSCAN_DTXI() 00033 #define FMSTR_CAN_ERXI() FMSTR_MSCAN_ERXI() 00034 #define FMSTR_CAN_DRXI() FMSTR_MSCAN_DRXI() 00035 #define FMSTR_CAN_TEST_RXFLG() FMSTR_MSCAN_TEST_RXFLG() 00036 #define FMSTR_CAN_CLEAR_RXFLG() FMSTR_MSCAN_CLEAR_RXFLG() 00037 #define FMSTR_CAN_TEST_TXFLG() FMSTR_MSCAN_TEST_TXFLG() 00038 #define FMSTR_CAN_GET_MBSTATUS() FMSTR_MSCAN_GET_MBSTATUS() 00039 #define FMSTR_CAN_MAKEIDR0(id) FMSTR_MSCAN_MAKEIDR0(id) 00040 #define FMSTR_CAN_MAKEIDR1(id) FMSTR_MSCAN_MAKEIDR1(id) 00041 #define FMSTR_CAN_MAKEIDR2(id) FMSTR_MSCAN_MAKEIDR2(id) 00042 #define FMSTR_CAN_MAKEIDR3(id) FMSTR_MSCAN_MAKEIDR3(id) 00043 00044 #define FMSTR_CAN_TCTX FMSTR_MSCAN_TCTX 00045 #define FMSTR_CAN_TCFG(pctx) FMSTR_MSCAN_TCFG(pctx) 00046 #define FMSTR_CAN_TID(pctx, idr0, idr1, idr2, idr3) FMSTR_MSCAN_TID(pctx, idr0, idr1, idr2, idr3) 00047 #define FMSTR_CAN_TLEN(pctx, len) FMSTR_MSCAN_TLEN(pctx, len) 00048 #define FMSTR_CAN_TPRI(pctx, txPri) FMSTR_MSCAN_TPRI(pctx, txPri) 00049 #define FMSTR_CAN_PUTBYTE(pctx, dataByte) FMSTR_MSCAN_PUTBYTE(pctx, dataByte) 00050 #define FMSTR_CAN_TX(pctx) FMSTR_MSCAN_TX(pctx) 00051 00052 #define FMSTR_CAN_RCTX FMSTR_MSCAN_RCTX 00053 #define FMSTR_CAN_RINIT(idr0, idr1, idr2, idr3) FMSTR_MSCAN_RINIT(idr0, idr1, idr2, idr3) 00054 #define FMSTR_CAN_TINIT(idr0, idr1, idr2, idr3) FMSTR_MSCAN_TINIT(idr0, idr1, idr2, idr3) 00055 #define FMSTR_CAN_RCFG() FMSTR_MSCAN_RCFG() 00056 #define FMSTR_CAN_RX(pctx) FMSTR_MSCAN_RX(pctx) 00057 #define FMSTR_CAN_TEST_RIDR(pctx, idr0, idr1, idr2, idr3) FMSTR_MSCAN_TEST_RIDR(pctx, idr0, idr1, idr2, idr3) 00058 #define FMSTR_CAN_RLEN(pctx) FMSTR_MSCAN_RLEN(pctx) 00059 #define FMSTR_CAN_GETBYTE(pctx) FMSTR_MSCAN_GETBYTE(pctx) 00060 #define FMSTR_CAN_RFINISH(pctx) FMSTR_MSCAN_RFINISH(pctx) 00061 00062 #elif FMSTR_USE_FLEXCAN 00063 00064 #define FMSTR_CAN_ETXI() FMSTR_FCAN_ETXI() 00065 #define FMSTR_CAN_DTXI() FMSTR_FCAN_DTXI() 00066 #define FMSTR_CAN_ERXI() FMSTR_FCAN_ERXI() 00067 #define FMSTR_CAN_DRXI() FMSTR_FCAN_DRXI() 00068 #define FMSTR_CAN_TEST_RXFLG() FMSTR_FCAN_TEST_RXFLG() 00069 #define FMSTR_CAN_CLEAR_RXFLG() FMSTR_FCAN_CLEAR_RXFLG() 00070 #define FMSTR_CAN_TEST_TXFLG() FMSTR_FCAN_TEST_TXFLG() 00071 #define FMSTR_CAN_GET_MBSTATUS() FMSTR_FCAN_GET_MBSTATUS() 00072 #define FMSTR_CAN_MAKEIDR0(id) FMSTR_FCAN_MAKEIDR0(id) 00073 #define FMSTR_CAN_MAKEIDR1(id) FMSTR_FCAN_MAKEIDR1(id) 00074 #define FMSTR_CAN_MAKEIDR2(id) FMSTR_FCAN_MAKEIDR2(id) 00075 #define FMSTR_CAN_MAKEIDR3(id) FMSTR_FCAN_MAKEIDR3(id) 00076 00077 #define FMSTR_CAN_TCTX FMSTR_FCAN_TCTX 00078 #define FMSTR_CAN_TCFG(pctx) FMSTR_FCAN_TCFG(pctx) 00079 #define FMSTR_CAN_TID(pctx, idr0, idr1, idr2, idr3) FMSTR_FCAN_TID(pctx, idr0, idr1, idr2, idr3) 00080 #define FMSTR_CAN_TLEN(pctx, len) FMSTR_FCAN_TLEN(pctx, len) 00081 #define FMSTR_CAN_TPRI(pctx, txPri) FMSTR_FCAN_TPRI(pctx, txPri) 00082 #define FMSTR_CAN_PUTBYTE(pctx, dataByte) FMSTR_FCAN_PUTBYTE(pctx, dataByte) 00083 #define FMSTR_CAN_TX(pctx) FMSTR_FCAN_TX(pctx) 00084 00085 #define FMSTR_CAN_RCTX FMSTR_FCAN_RCTX 00086 #define FMSTR_CAN_RINIT(idr0, idr1, idr2, idr3) FMSTR_FCAN_RINIT(idr0, idr1, idr2, idr3) 00087 #define FMSTR_CAN_TINIT(idr0, idr1, idr2, idr3) FMSTR_FCAN_TINIT(idr0, idr1, idr2, idr3) 00088 #define FMSTR_CAN_RCFG() FMSTR_FCAN_RCFG() 00089 #define FMSTR_CAN_RX(pctx) FMSTR_FCAN_RX(pctx) 00090 #define FMSTR_CAN_TEST_RIDR(pctx, idr0, idr1, idr2, idr3) FMSTR_FCAN_TEST_RIDR(pctx, idr0, idr1, idr2, idr3) 00091 #define FMSTR_CAN_RLEN(pctx) FMSTR_FCAN_RLEN(pctx) 00092 #define FMSTR_CAN_GETBYTE(pctx) FMSTR_FCAN_GETBYTE(pctx) 00093 #define FMSTR_CAN_RFINISH(pctx) FMSTR_FCAN_RFINISH(pctx) 00094 00095 #else 00096 #error CAN interface undefined 00097 #endif 00098 00099 /*********************************** 00100 * local variables 00101 ***********************************/ 00102 00103 /* FreeMASTER communication buffer (in/out) plus the STS and LEN bytes */ 00104 static FMSTR_BCHR pcm_pCommBuffer[FMSTR_COMM_BUFFER_SIZE+3]; 00105 00106 /* FreeMASTER runtime flags */ 00107 /*lint -e{960} using union */ 00108 static volatile union 00109 { 00110 FMSTR_FLAGS all; 00111 00112 struct 00113 { 00114 unsigned bTxActive : 1; /* response is just being transmitted */ 00115 unsigned bTxFirst : 1; /* first frame to be send out */ 00116 unsigned bRxActive : 1; /* just in the middle of receiving (fragmented) frame */ 00117 unsigned bRxFirst : 1; /* expecting the first frame (FST) */ 00118 unsigned bRxTgl1 : 1; /* expecting TGL=1 in next frame */ 00119 unsigned bRxFrameReady : 1; /* frame received (waiting to be handled in poll) */ 00120 unsigned bRxSpecial : 1; /* special command received (not passed to ProtocolDecode) */ 00121 00122 } flg; 00123 00124 } pcm_wFlags; 00125 00126 /* receive and transmit buffers and counters */ 00127 static FMSTR_SIZE8 pcm_nTxTodo; /* transmission to-do counter (0 when tx is idle) */ 00128 static FMSTR_BPTR pcm_pTxBuff; /* pointer to next byte to transmit */ 00129 static FMSTR_SIZE8 pcm_nRxCtr; /* how many bytes received (total across all fragments) */ 00130 static FMSTR_BPTR pcm_pRxBuff; /* pointer to next free place in RX buffer */ 00131 static FMSTR_BCHR pcm_nRxErr; /* error raised during receive process */ 00132 static FMSTR_BCHR pcm_nRxCheckSum; /* checksum of data being received */ 00133 static FMSTR_U8 pcm_uTxCtlByte; 00134 static FMSTR_U8 pcm_uTxFrmCtr; /* TX CAN frame counter (within one FreeMASTER frame) */ 00135 00136 #if FMSTR_CAN_CMDID_DYNAMIC 00137 static FMSTR_U8 pcm_cmdIdr[4] = 00138 { 00139 FMSTR_CAN_MAKEIDR0(FMSTR_CAN_CMDID), 00140 FMSTR_CAN_MAKEIDR1(FMSTR_CAN_CMDID), 00141 FMSTR_CAN_MAKEIDR2(FMSTR_CAN_CMDID), 00142 FMSTR_CAN_MAKEIDR3(FMSTR_CAN_CMDID) 00143 }; 00144 00145 #define FMSTR_CAN_CMDID_IDR0 pcm_cmdIdr[0] 00146 #define FMSTR_CAN_CMDID_IDR1 pcm_cmdIdr[1] 00147 #define FMSTR_CAN_CMDID_IDR2 pcm_cmdIdr[2] 00148 #define FMSTR_CAN_CMDID_IDR3 pcm_cmdIdr[3] 00149 #else 00150 #define FMSTR_CAN_CMDID_IDR0 FMSTR_CAN_MAKEIDR0(FMSTR_CAN_CMDID) 00151 #define FMSTR_CAN_CMDID_IDR1 FMSTR_CAN_MAKEIDR1(FMSTR_CAN_CMDID) 00152 #define FMSTR_CAN_CMDID_IDR2 FMSTR_CAN_MAKEIDR2(FMSTR_CAN_CMDID) 00153 #define FMSTR_CAN_CMDID_IDR3 FMSTR_CAN_MAKEIDR3(FMSTR_CAN_CMDID) 00154 #endif 00155 00156 #if FMSTR_CAN_RESPID_DYNAMIC 00157 static FMSTR_U8 pcm_respIdr[4] = 00158 { 00159 FMSTR_CAN_MAKEIDR0(FMSTR_CAN_CMDID), 00160 FMSTR_CAN_MAKEIDR1(FMSTR_CAN_CMDID), 00161 FMSTR_CAN_MAKEIDR2(FMSTR_CAN_CMDID), 00162 FMSTR_CAN_MAKEIDR3(FMSTR_CAN_CMDID) 00163 }; 00164 00165 #define FMSTR_CAN_RESPID_IDR0 pcm_respIdr[0] 00166 #define FMSTR_CAN_RESPID_IDR1 pcm_respIdr[1] 00167 #define FMSTR_CAN_RESPID_IDR2 pcm_respIdr[2] 00168 #define FMSTR_CAN_RESPID_IDR3 pcm_respIdr[3] 00169 #else 00170 #define FMSTR_CAN_RESPID_IDR0 FMSTR_CAN_MAKEIDR0(FMSTR_CAN_RESPID) 00171 #define FMSTR_CAN_RESPID_IDR1 FMSTR_CAN_MAKEIDR1(FMSTR_CAN_RESPID) 00172 #define FMSTR_CAN_RESPID_IDR2 FMSTR_CAN_MAKEIDR2(FMSTR_CAN_RESPID) 00173 #define FMSTR_CAN_RESPID_IDR3 FMSTR_CAN_MAKEIDR3(FMSTR_CAN_RESPID) 00174 #endif 00175 00176 /*********************************** 00177 * local function prototypes 00178 ***********************************/ 00179 00180 static void FMSTR_Listen(void); 00181 static void FMSTR_RxDone(void); 00182 static void FMSTR_SendError(FMSTR_BCHR nErrCode); 00183 00184 /**************************************************************************/ 00190 void FMSTR_InitCan(void) 00191 { 00192 /* initialize all state variables */ 00193 pcm_wFlags.all = 0U; 00194 pcm_nTxTodo = 0U; 00195 00196 /* configure CAN receiving (used by FlexCAN to setup MB) */ 00197 FMSTR_CAN_RINIT(FMSTR_CAN_CMDID_IDR0, FMSTR_CAN_CMDID_IDR1, \ 00198 FMSTR_CAN_CMDID_IDR2, FMSTR_CAN_CMDID_IDR3); 00199 00200 /* configure CAN transmitting (used by FlexCAN to setup MB) */ 00201 FMSTR_CAN_TINIT(FMSTR_CAN_CMDID_IDR0, FMSTR_CAN_CMDID_IDR1, \ 00202 FMSTR_CAN_CMDID_IDR2, FMSTR_CAN_CMDID_IDR3); 00203 00204 /* start listening for commands */ 00205 FMSTR_Listen(); 00206 } 00207 00208 void FMSTR_SetCanCmdID(FMSTR_U32 canID) 00209 { 00210 #if FMSTR_CAN_CMDID_DYNAMIC 00211 pcm_cmdIdr[0] = FMSTR_CAN_MAKEIDR0(canID); 00212 pcm_cmdIdr[1] = FMSTR_CAN_MAKEIDR1(canID); 00213 pcm_cmdIdr[2] = FMSTR_CAN_MAKEIDR2(canID); 00214 pcm_cmdIdr[3] = FMSTR_CAN_MAKEIDR3(canID); 00215 #else 00216 FMSTR_UNUSED(canID); 00217 #endif 00218 } 00219 00220 void FMSTR_SetCanRespID(FMSTR_U32 canID) 00221 { 00222 #if FMSTR_CAN_RESPID_DYNAMIC 00223 pcm_respIdr[0] = FMSTR_CAN_MAKEIDR0(canID); 00224 pcm_respIdr[1] = FMSTR_CAN_MAKEIDR1(canID); 00225 pcm_respIdr[2] = FMSTR_CAN_MAKEIDR2(canID); 00226 pcm_respIdr[3] = FMSTR_CAN_MAKEIDR3(canID); 00227 #else 00228 FMSTR_UNUSED(canID); 00229 #endif 00230 } 00231 00232 /**************************************************************************/ 00238 static void FMSTR_Listen(void) 00239 { 00240 /* disable transmitter state machine */ 00241 pcm_wFlags.flg.bTxActive = 0U; 00242 00243 /* wait for first frame */ 00244 pcm_wFlags.flg.bRxFrameReady = 0U; 00245 pcm_wFlags.flg.bRxFirst = 1U; 00246 pcm_wFlags.flg.bRxActive = 1U; 00247 00248 /* enable CAN receiving */ 00249 FMSTR_CAN_RCFG(); 00250 00251 #if FMSTR_LONG_INTR || FMSTR_SHORT_INTR 00252 FMSTR_CAN_ERXI(); 00253 #endif 00254 } 00255 00256 /**************************************************************************/ 00264 static void FMSTR_SendError(FMSTR_BCHR nErrCode) 00265 { 00266 /* fill & send single-byte response */ 00267 *pcm_pCommBuffer = nErrCode; 00268 FMSTR_SendResponse(pcm_pCommBuffer, 1U); 00269 } 00270 00271 /**************************************************************************/ 00283 void FMSTR_SendResponse(FMSTR_BPTR pResponse, FMSTR_SIZE8 nLength) 00284 { 00285 FMSTR_U16 chSum = 0U; 00286 FMSTR_U8 i, c; 00287 00288 /* remember the buffer to be sent */ 00289 pcm_pTxBuff = pResponse; 00290 00291 /* status byte and data are already there, compute checksum only */ 00292 for (i=0U; i<nLength; i++) 00293 { 00294 c = 0U; 00295 pResponse = FMSTR_ValueFromBuffer8(&c, pResponse); 00296 /* add character to checksum */ 00297 chSum += c; 00298 /* prevent saturation to happen on DSP platforms */ 00299 chSum &= 0xffU; 00300 } 00301 00302 /* store checksum after the message */ 00303 pResponse = FMSTR_ValueToBuffer8(pResponse, (FMSTR_U8) (((FMSTR_U16)~(chSum)) + 1U)); 00304 00305 /* send the message and the checksum */ 00306 pcm_nTxTodo = (FMSTR_SIZE8) (nLength + 1U); 00307 00308 /* now transmitting the response */ 00309 pcm_wFlags.flg.bTxActive = 1U; 00310 pcm_wFlags.flg.bTxFirst = 1U; 00311 00312 /* enable TX interrupt */ 00313 #if FMSTR_LONG_INTR || FMSTR_SHORT_INTR 00314 FMSTR_CAN_ETXI(); 00315 #endif 00316 #if (FMSTR_SHORT_INTR) && (FMSTR_USE_FLEXCAN) 00317 FMSTR_ProcessCanTx(); 00318 #endif 00319 } 00320 00321 /**************************************************************************/ 00333 FMSTR_BOOL FMSTR_TxCan(void) 00334 { 00335 FMSTR_U8 ch; 00336 FMSTR_CAN_TCTX tctx; 00337 FMSTR_SIZE8 len = pcm_nTxTodo; 00338 00339 if(!pcm_wFlags.flg.bTxActive || !pcm_nTxTodo) 00340 return FMSTR_FALSE; 00341 00342 if(len > 7) 00343 len = 7; 00344 00345 /* first byte is control */ 00346 if(pcm_wFlags.flg.bTxFirst) 00347 { 00348 /* the first frame and the length*/ 00349 pcm_uTxCtlByte = (FMSTR_U8) (FMSTR_CANCTL_FST | len); 00350 pcm_uTxFrmCtr = 0U; 00351 pcm_wFlags.flg.bTxFirst = 0U; 00352 } 00353 else 00354 { 00355 /* the next frame */ 00356 pcm_uTxCtlByte &= ~(FMSTR_CANCTL_FST | FMSTR_CANCTL_LEN_MASK); 00357 pcm_uTxCtlByte ^= FMSTR_CANCTL_TGL; 00358 pcm_uTxCtlByte |= len; 00359 pcm_uTxFrmCtr++; 00360 } 00361 00362 /* prepare transmit buffer */ 00363 FMSTR_CAN_TCFG(&tctx); 00364 00365 /* set transmit priority and ID */ 00366 FMSTR_CAN_TPRI(&tctx, pcm_uTxFrmCtr); 00367 FMSTR_CAN_TID(&tctx, FMSTR_CAN_RESPID_IDR0, 00368 FMSTR_CAN_RESPID_IDR1, FMSTR_CAN_RESPID_IDR2, FMSTR_CAN_RESPID_IDR3); 00369 00370 /* is it the last frame? */ 00371 pcm_nTxTodo -= len; 00372 if(!pcm_nTxTodo) 00373 pcm_uTxCtlByte |= FMSTR_CANCTL_LST; 00374 00375 /* set frame len */ 00376 FMSTR_CAN_TLEN(&tctx, (FMSTR_U8) (len+1)); 00377 00378 /* put control byte */ 00379 FMSTR_CAN_PUTBYTE(&tctx, pcm_uTxCtlByte); 00380 00381 /* put data part */ 00382 while(len--) 00383 { 00384 pcm_pTxBuff = FMSTR_ValueFromBuffer8(&ch, pcm_pTxBuff); 00385 FMSTR_CAN_PUTBYTE(&tctx, ch); 00386 } 00387 00388 /* submit frame for transmission */ 00389 FMSTR_CAN_TX(&tctx); 00390 00391 /* if the full frame is safe in tx buffer(s), release the received command */ 00392 if(!pcm_nTxTodo) 00393 { 00394 /* no more transmitting */ 00395 pcm_wFlags.flg.bTxActive = 0U; 00396 00397 /* start listening immediately (also frees the last received frame) */ 00398 FMSTR_Listen(); 00399 } 00400 00401 /* returning TRUE, frame was sent */ 00402 return FMSTR_TRUE; 00403 } 00404 00405 00406 /**************************************************************************/ 00414 FMSTR_BOOL FMSTR_RxCan(void) 00415 { 00416 FMSTR_CAN_RCTX rctx; 00417 FMSTR_SIZE8 len; 00418 FMSTR_U8 ctl, ch; 00419 00420 if(!pcm_wFlags.flg.bRxActive) 00421 return FMSTR_FALSE; 00422 00423 /* last FreeMASTER frame not yet handled */ 00424 if(pcm_wFlags.flg.bRxFrameReady) 00425 return FMSTR_FALSE; 00426 00427 /* get the frame */ 00428 FMSTR_CAN_RX(&rctx); 00429 00430 /* test message ID is it matches the CMDID */ 00431 if(!FMSTR_CAN_TEST_RIDR(&rctx, FMSTR_CAN_CMDID_IDR0, FMSTR_CAN_CMDID_IDR1, 00432 FMSTR_CAN_CMDID_IDR2, FMSTR_CAN_CMDID_IDR3)) 00433 { 00434 FMSTR_CAN_RFINISH(&rctx); 00435 return FMSTR_FALSE; 00436 } 00437 00438 /* get the first (control) byte */ 00439 ctl = FMSTR_CAN_GETBYTE(&rctx); 00440 00441 /* should be master-to-slave (otherwise perhaps a self-received frame) */ 00442 if(!(ctl & FMSTR_CANCTL_M2S)) 00443 goto frame_contd; 00444 00445 /* first frame resets the state machine */ 00446 if((ctl & FMSTR_CANCTL_FST) || pcm_wFlags.flg.bRxFirst) 00447 { 00448 if(!(ctl & FMSTR_CANCTL_FST) || /* must be the first frame! */ 00449 (ctl & FMSTR_CANCTL_TGL)) /* TGL must be zero! */ 00450 { 00451 /* frame is ours, but we ignore it */ 00452 goto frame_contd; 00453 } 00454 00455 /* now receive the rest of bigger FreeMASTER frame */ 00456 pcm_wFlags.flg.bRxFirst = 0U; 00457 pcm_wFlags.flg.bRxTgl1 = 1U; 00458 00459 /* special command? */ 00460 if(ctl & FMSTR_CANCTL_SPC) 00461 pcm_wFlags.flg.bRxSpecial = 1U; 00462 else 00463 pcm_wFlags.flg.bRxSpecial = 0U; 00464 00465 /* start receiving the frame */ 00466 pcm_pRxBuff = pcm_pCommBuffer; 00467 pcm_nRxCheckSum = 0; 00468 pcm_nRxCtr = 0; 00469 pcm_nRxErr = 0; 00470 } 00471 else 00472 { 00473 /* toggle bit should match */ 00474 if((pcm_wFlags.flg.bRxTgl1 && !(ctl & FMSTR_CANCTL_TGL)) || 00475 (!pcm_wFlags.flg.bRxTgl1 && (ctl & FMSTR_CANCTL_TGL))) 00476 { 00477 /* invalid sequence detected */ 00478 pcm_nRxErr = FMSTR_STC_CANTGLERR; 00479 goto frame_done; 00480 } 00481 00482 /* expect next frame toggled again */ 00483 pcm_wFlags.flg.bRxTgl1 ^= 1U; 00484 } 00485 00486 /* frame is valid, get the data */ 00487 len = (FMSTR_SIZE8) (ctl & FMSTR_CANCTL_LEN_MASK); 00488 00489 /* sanity check of the len field */ 00490 if(len >= FMSTR_CAN_RLEN(&rctx)) 00491 { 00492 /* invalid frame length, re-start receiving */ 00493 pcm_nRxErr = FMSTR_STC_CANMSGERR; 00494 goto frame_done; 00495 } 00496 00497 /* will data fit? */ 00498 if((pcm_nRxCtr+len) > FMSTR_COMM_BUFFER_SIZE) 00499 { 00500 /* this frame must be ignored, start receiving again */ 00501 pcm_nRxErr = FMSTR_STC_CANMSGERR; 00502 goto frame_done; 00503 } 00504 00505 /* okay, receive all data bytes */ 00506 pcm_nRxCtr += len; 00507 while(len--) 00508 { 00509 ch = FMSTR_CAN_GETBYTE(&rctx); 00510 pcm_pRxBuff = FMSTR_ValueToBuffer8(pcm_pRxBuff, ch); 00511 pcm_nRxCheckSum += ch; 00512 } 00513 00514 /* was it the last frame? */ 00515 if(!(ctl & FMSTR_CANCTL_LST)) 00516 goto frame_contd; 00517 00518 /* done with the FreeMASTER frame, it will be handled later in RxDone */ 00519 frame_done: 00520 /* disable receiver so it does not corrupt the frame until it is handled */ 00521 pcm_wFlags.flg.bRxActive = 0; 00522 /* frame received. Checksum and frame will be checked later in RxDone */ 00523 pcm_wFlags.flg.bRxFrameReady = 1U; 00524 00525 /* frame will continue by next chunk next time */ 00526 frame_contd: 00527 FMSTR_CAN_RFINISH(&rctx); 00528 return FMSTR_TRUE; 00529 } 00530 00531 /**************************************************************************/ 00537 static void FMSTR_RxDone(void) 00538 { 00539 /* frame really here? */ 00540 if(!pcm_wFlags.flg.bRxFrameReady) 00541 return ; 00542 00543 /* acknowledge the flag, we're going to process the frame now */ 00544 pcm_wFlags.flg.bRxFrameReady = 0U; 00545 00546 /* any fragmentation error detected during the receive process? */ 00547 if(!pcm_nRxErr) 00548 { 00549 /* check for our standard frame errors */ 00550 00551 /* checksum should be zero */ 00552 if(pcm_nRxCheckSum) 00553 { 00554 pcm_nRxErr = FMSTR_STC_CMDCSERR; 00555 } 00556 /* checksum okay, check frame length */ 00557 else 00558 { 00559 FMSTR_BPTR pFrame = pcm_pCommBuffer; 00560 FMSTR_BCHR len; 00561 00562 pFrame = FMSTR_ValueFromBuffer8(&len, pFrame); 00563 00564 /* fast command? */ 00565 if((len & FMSTR_FASTCMD) == FMSTR_FASTCMD) 00566 { 00567 /* get length */ 00568 len = (FMSTR_BCHR)((len & FMSTR_FASTCMD_DATALEN_MASK) >> FMSTR_FASTCMD_DATALEN_SHIFT); 00569 00570 /* add command-byte and checksum (are included in the nRxCtr) */ 00571 len += 2; 00572 } 00573 /* std command */ 00574 else 00575 { 00576 /* get length */ 00577 pFrame = FMSTR_ValueFromBuffer8(&len, pFrame); 00578 00579 /* add command-byte, length and checksum (are included in the nRxCtr) */ 00580 len += 3; 00581 } 00582 00583 /* now the len received should match the data bytes received */ 00584 if(pcm_nRxCtr != len) 00585 pcm_nRxErr = FMSTR_STC_CMDCSERR; 00586 } 00587 } 00588 00589 /* any error? */ 00590 if(pcm_nRxErr) 00591 { 00592 FMSTR_SendError(FMSTR_STC_CMDCSERR); 00593 } 00594 /* no error */ 00595 else 00596 { 00597 /* special CAN command? for our layer */ 00598 if(pcm_wFlags.flg.bRxSpecial) 00599 { 00600 FMSTR_BPTR pFrame = pcm_pCommBuffer; 00601 FMSTR_BCHR c; 00602 00603 /* get the command */ 00604 FMSTR_ValueFromBuffer8(&c, pFrame); 00605 00606 switch(c) 00607 { 00608 case FMSTR_CANSPC_PING: 00609 FMSTR_SendError(FMSTR_STS_OK); 00610 break; 00611 00612 default: 00613 /* unknown command */ 00614 FMSTR_SendError(FMSTR_STC_INVCMD); 00615 } 00616 } 00617 /* standard FreeMASTER command to be passed above */ 00618 else 00619 { 00620 /* decode and handle frame by SCI classic driver */ 00621 if(!FMSTR_ProtocolDecoder(pcm_pCommBuffer)) 00622 { 00623 /* if no response was generated, start listening again, otherwise, 00624 the receive will be initiated after transmission is complete in 00625 FMSTR_TxCan (this prevents our TX buffer to be corrupted by RX) */ 00626 FMSTR_Listen(); 00627 } 00628 } 00629 } 00630 } 00631 00632 /**************************************************************************/ 00640 void FMSTR_ProcessCanRx(void) 00641 { 00642 if(FMSTR_CAN_TEST_RXFLG()) 00643 { 00644 /* process the CAN frame */ 00645 FMSTR_RxCan(); 00646 00647 /* CAN frame handled, release the flag */ 00648 FMSTR_CAN_CLEAR_RXFLG(); 00649 00650 #if FMSTR_LONG_INTR 00651 /* handle completed frame now? (may be we're in the interrupt) */ 00652 if(pcm_wFlags.flg.bRxFrameReady) 00653 FMSTR_RxDone(); 00654 #endif 00655 } 00656 } 00657 00658 /**************************************************************************/ 00666 void FMSTR_ProcessCanTx(void) 00667 { 00668 #if FMSTR_USE_MSCAN 00669 /* any TX buffer available? */ 00670 if(FMSTR_CAN_TEST_TXFLG()) 00671 { 00672 #if FMSTR_SHORT_INTR || FMSTR_LONG_INTR 00673 /* send one CAN frame (fills buffer and clears its TXFLG */ 00674 if(!FMSTR_TxCan()) 00675 { 00676 /* no more frames, disable TX Interrupt */ 00677 FMSTR_CAN_DTXI(); 00678 } 00679 #else 00680 /* send if you have anything to be sent */ 00681 FMSTR_TxCan(); 00682 #endif 00683 } 00684 #elif FMSTR_USE_FLEXCAN 00685 00686 /* is TX buffer ready for next packet? */ 00687 if((FMSTR_CAN_GET_MBSTATUS()) == FMSTR_FCANMB_CTXREADY) 00688 { 00689 #if FMSTR_SHORT_INTR || FMSTR_LONG_INTR 00690 /* send one CAN frame (fills buffer and clears its TXFLG */ 00691 if(!FMSTR_TxCan()) 00692 { 00693 /* no more frames, disable TX Interrupt */ 00694 FMSTR_CAN_DTXI(); 00695 } 00696 #else 00697 /* send if you have anything to be sent */ 00698 FMSTR_TxCan(); 00699 #endif 00700 } 00701 #endif 00702 } 00703 00704 /******************************************************************************* 00705 * 00706 * @brief API: Main "Polling" call from the application main loop 00707 * 00708 *******************************************************************************/ 00709 00710 void FMSTR_Poll(void) 00711 { 00712 /* handle the physical CAN module */ 00713 #if FMSTR_POLL_DRIVEN 00714 FMSTR_ProcessCanRx(); 00715 FMSTR_ProcessCanTx(); 00716 #endif 00717 00718 #if FMSTR_POLL_DRIVEN || FMSTR_SHORT_INTR 00719 00720 /* except in the LONG_INTR mode, the frame gets handled here */ 00721 if(pcm_wFlags.flg.bRxFrameReady) 00722 FMSTR_RxDone(); 00723 #endif 00724 } 00725 00726 #endif /* FMSTR_USE_CAN */ 00727